package com.google.jessewilson.codesearch.util;

import com.google.inject.Provider;

/**
 * @author jessewilson
 */
public class PushProvider<T> implements Provider<T> {

  private static Object NO_VALUE = new Object();

  private final ThreadLocal<T> threadLocal = new ThreadLocal<T>() {
    protected T initialValue() {
      return (T)NO_VALUE;
    }
  };

  public void push(T value) {
    T currentValue = threadLocal.get();
    if (currentValue != NO_VALUE) {
      throw new IllegalStateException("Cannot push() multiple times");
    }

    threadLocal.set(value);
  }

  public void pop() {
    T currentValue = threadLocal.get();
    if (currentValue == NO_VALUE) {
      throw new IllegalStateException("pop() without a prior push");
    }

    threadLocal.set((T)NO_VALUE);
  }


  public T get() {
    T currentValue = threadLocal.get();
    if (currentValue == NO_VALUE) {
      throw new IllegalStateException("get() without a prior push");
    }

    return currentValue;
  }
}
